package com.jwong.common.web.interceptor;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.util.StringUtils;

public class ClientOAuth2FeignRequestInterceptor implements RequestInterceptor {

    public static final String AUTHORIZATION = "Authorization";
    public static final String BEARER = "Bearer";
    public static final String BASIC = "Basic";

    @Override
    public void apply(RequestTemplate template) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication instanceof OAuth2Authentication) {
            OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
            OAuth2AuthenticationDetails authenticationDetails = (OAuth2AuthenticationDetails)oAuth2Authentication.getDetails();
            String accessToken = this.extract(authenticationDetails);
            if (StringUtils.hasText(accessToken))
                template.header(ClientOAuth2FeignRequestInterceptor.AUTHORIZATION, accessToken);
        }

    }

    protected String extract(OAuth2AuthenticationDetails authenticationDetails) {
        String accessToken = authenticationDetails.getTokenValue();
        String tokenType = authenticationDetails.getTokenType();
        if (StringUtils.hasText(accessToken)) {
            if (StringUtils.startsWithIgnoreCase(accessToken, ClientOAuth2FeignRequestInterceptor.BEARER)) {
                return accessToken;
            } else {
                return String.format("%s %s", tokenType, accessToken);
            }
        }
        return null;
    }

}